package com.woniuxy.signing.app.controller;

import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.net.URLConnection;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.woniuxy.commons.exception.MyException;
import com.woniuxy.commons.util.GetTokenUserLogin;
import com.woniuxy.commons.util.LoginUserDto;
import com.woniuxy.commons.util.Result;
import com.woniuxy.commons.util.UserDto;
import com.woniuxy.signing.app.util.TokenToUserDtoUtil;
import com.woniuxy.signing.client.CocahSigningVenueClient;
import com.woniuxy.signing.client.form.CocahSigningVenueForm;
import com.woniuxy.signing.client.form.MakeSureSignForm;
import com.woniuxy.signing.common.OssTemplate;
import com.woniuxy.signing.common.SigningException;
import com.woniuxy.signing.common.SigningResultCode;
import com.woniuxy.signing.infra.model.Agreement;
import com.woniuxy.signing.infra.model.CocahSigningVenue;
import com.woniuxy.signing.service.AgreementService;
import com.woniuxy.signing.service.CocahSigningVenueService;
import com.woniuxy.userapp.client.CoachClient;
import com.woniuxy.userapp.client.VenueClient;
import com.woniuxy.userapp.client.param.CoachInfo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.validation.Valid;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Pattern;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 前端控制器
 * </p>
 *
 * @author huanglei
 * @since 2022-08-07
 */
@RestController
@Validated
@Api("教练签约场馆相关接口")
public class CocahSigningVenueController implements CocahSigningVenueClient {

    @Resource
    private OssTemplate ossTemplate;

    @Autowired
    private CocahSigningVenueService cocahSigningVenueService;

    @Resource
    private VenueClient venueClient;

    @Resource
    private AgreementService agreementService;

    @Resource
    private CoachClient coachClient;


    /*
     * @Description:
     * @param
     * @return: com.woniuxy.commons.util.Result
     * @Author: 黄磊
     * @Date: 2022/8/7 14:59
     */
    @PostMapping("/cocahSigningVenue/cocahSigningVenue")
    @ApiOperation("当前登录教练签约|续约|解除约定后重新签约")
    public Result cocahSigningVenue(@Valid @RequestBody CocahSigningVenueForm cocahSigningVenueForm) throws JsonProcessingException, UnsupportedEncodingException {

        //1.判断url是否存在资源
        makeSureURL(cocahSigningVenueForm.getAgreementUri());

        //2.判断当前时间和合约开始时间
        if (stringToLong(cocahSigningVenueForm.getAgreementStartTime()) < new Date().getTime()) {
            throw new SigningException(SigningResultCode.SIGNING_TIEMFAIL1.getCode(), SigningResultCode.SIGNING_TIEMFAIL1.getMessage());
        }

        //3.判断是否结束时间>开始时间>=结束时间
        if (stringToLong(cocahSigningVenueForm.getAgreementStartTime()) >= stringToLong(cocahSigningVenueForm.getAgreementFinishTime())) {
            throw new SigningException(SigningResultCode.SIGNING_TIMEFAIL.getCode(), SigningResultCode.SIGNING_TIMEFAIL.getMessage());
        }


        LoginUserDto tokenUserLogin = GetTokenUserLogin.getTokenUserLogin();
        System.out.println(tokenUserLogin);

        //1.教练登录账号
        CoachInfo coachInfo = coachClient.findCoachByAccountId(tokenUserLogin.getLoginId().intValue()).getData();
        Integer loginCoachId = coachInfo.getId();
        String loginCoachName = coachInfo.getName();


        //2.场馆名
        Integer accountId = venueClient.findAccountIdByVenueId(Integer.parseInt(cocahSigningVenueForm.getVenueId().trim())).getData();
        if (accountId == null) {
            throw new MyException(9000, "场馆不存在");
        }
        String venueName = venueClient.findVenueByAccountId(accountId).getData().getVenueName();


        //2.是否存在该场馆
        Result<Integer> venueIdResult = venueClient.findAccountIdByVenueId(Integer.parseInt(cocahSigningVenueForm.getVenueId()));
        System.out.println(venueIdResult);
        if (venueIdResult.getData() == null) {
            throw new SigningException(SigningResultCode.VUEN_NOTEXIST.getCode(), SigningResultCode.VUEN_NOTEXIST.getMessage());
        }

        //3.是否已经和该场馆签约
        CocahSigningVenue cocahSigningVenueDB = cocahSigningVenueService.getOne(new QueryWrapper<CocahSigningVenue>().eq("cocah_id", loginCoachId));
        if (cocahSigningVenueDB == null) {
            //1.生成合同
            Agreement agreement = new Agreement();
            agreement.setAgreementContent(loginCoachName + "和" + venueName + "签订的合同");
            agreement.setPartAName(loginCoachName);
            agreement.setPartBName(venueName);
            agreement.setAgreementSignTime(LocalDateTime.now());
            agreement.setAgreementStartTime(cocahSigningVenueForm.getAgreementStartTime());
            agreement.setAgreementFinishTime(cocahSigningVenueForm.getAgreementFinishTime());
            agreement.setAgreementUri(cocahSigningVenueForm.getAgreementUri());
            agreement.setAgreementState(0);
            agreementService.save(agreement);


            //2.生成签约关系表
            CocahSigningVenue cocahSigningVenue = new CocahSigningVenue();
            cocahSigningVenue.setCocahId(loginCoachId);
            cocahSigningVenue.setVenueId(Integer.parseInt(cocahSigningVenueForm.getVenueId().trim()));
            cocahSigningVenue.setAgreementId(agreement.getId());
            cocahSigningVenue.setState(0);
            cocahSigningVenueService.saveOrUpdate(cocahSigningVenue);
            return Result.getInstance().setMsg("签约成功");
        }

        if (cocahSigningVenueDB != null && cocahSigningVenueDB.getState() != 0) {
            //根据 签约关系id 获得签约对象
            Agreement agreementDB = agreementService.getOne(new QueryWrapper<Agreement>().eq("id", cocahSigningVenueDB.getAgreementId()));


            if (cocahSigningVenueDB.getState() == 0 || agreementDB.getAgreementState() == 0) {
                throw new SigningException(SigningResultCode.SIGNING_ISEXIST.getCode(), SigningResultCode.SIGNING_ISEXIST.getMessage());
            }


            cocahSigningVenueDB.setState(0);
            //1.更新关系
            cocahSigningVenueService.saveOrUpdate(cocahSigningVenueDB);

            //2.更新合同
            agreementDB.setAgreementState(0);
            agreementDB.setAgreementSignTime(LocalDateTime.now());
            agreementDB.setAgreementStartTime(cocahSigningVenueForm.getAgreementStartTime());
            agreementDB.setAgreementFinishTime(cocahSigningVenueForm.getAgreementFinishTime());


            agreementService.saveOrUpdate(agreementDB);

            return Result.getInstance().setMsg("续签或再次签约成功");
            //5.

        } else {
            throw new MyException(9999, "一个教练只能签约一个场馆");
        }


        //4.已经签约 且在合同有效内 不可以再次签约


        //4.如果是解约状态 则重新签约 和


//
    }

    @GetMapping("/cocahSigningVenue/liftAgreement")
    @ApiOperation("当前登录教练合同期限内解除某个场馆的合约")
    public Result liftAgreement(
            @Pattern(regexp = "-?\\d+(\\.\\d+)?", message = "场馆id不是数字类型的字符串")
            @NotNull(message = "场馆id不能是null")
            @NotBlank(message = "场馆id不能是空字符串")
            @Min(value = 1, message = "场馆id最小值为1")
            @RequestParam String venueId) {



        LoginUserDto tokenUserLogin = GetTokenUserLogin.getTokenUserLogin();
        CoachInfo coachInfo = coachClient.findCoachByAccountId(tokenUserLogin.getLoginId().intValue()).getData();
        Integer coachInfoId = coachInfo.getId();

        //1.这个合约存不存在
        CocahSigningVenue cocahSigningVenueDB = cocahSigningVenueService.getOne(new QueryWrapper<CocahSigningVenue>().eq("cocah_id", coachInfoId).eq("venue_id", venueId));
        if (cocahSigningVenueDB == null) {
            throw new SigningException(SigningResultCode.SIGNING_NOTEXIST.getCode(), SigningResultCode.SIGNING_NOTEXIST.getMessage());
        }


        //2.这个合约是不是自己的(1已经判断)

        //3.这个合约的状态为正常状态

        if (cocahSigningVenueDB.getState() != 0) {
            throw new SigningException(SigningResultCode.SIGNING_ISEXPIRE.getCode(), SigningResultCode.SIGNING_ISEXPIRE.getMessage());
        }
        //修改
        //改中间表状态
        cocahSigningVenueDB.setState(2);
        cocahSigningVenueService.saveOrUpdate(cocahSigningVenueDB);

        //改签约表状态、解约时间
        Agreement agreementDB = agreementService.getOne(new QueryWrapper<Agreement>().eq("id", cocahSigningVenueDB.getAgreementId()));
        if (agreementDB == null || agreementDB.getAgreementState() != 0) {
            throw new SigningException(SigningResultCode.AGREEMENT_ISDEFAULT.getCode(), SigningResultCode.AGREEMENT_ISDEFAULT.getMessage());
        }
        agreementDB.setAgreementRemoveTime(LocalDateTime.now());
        agreementDB.setAgreementState(2);
        agreementService.saveOrUpdate(agreementDB);
        return Result.getInstance().setMsg("解约成功");

    }

    @ApiOperation("签约附件上传")
    @PostMapping("/cocahSigningVenue/upload")
    public Result fileUpload(MultipartFile file) throws IOException {
        String oldName = file.getOriginalFilename();
        String preFix = oldName.substring(oldName.lastIndexOf("."));
        String newName = System.currentTimeMillis() + preFix;

        String url = ossTemplate.fileUpload(newName, file.getInputStream());
        if (url != null) {

            return Result.getInstance(String.class).setMsg("上传成功").setData(url);
        } else {
            return Result.getInstance().setMsg("上传失败");
        }
    }

    @ApiOperation("传入场馆和教练id查看是否有签约关系")
    @Override
    public Result makeSureSign(MakeSureSignForm makeSureSignForm) {
        CocahSigningVenue cocahSigningVenueDB = cocahSigningVenueService.getOne(new QueryWrapper<CocahSigningVenue>().eq("cocah_id", makeSureSignForm.getCocahId()).eq("venue_id", makeSureSignForm.getVenueId()).eq("state", 0));
        if (cocahSigningVenueDB != null) {
            return Result.getInstance().setCode(200).setMsg("存在签约关系");
        } else {
            return Result.getInstance().setCode(500).setMsg("不存在签约关系");
        }

    }

    @Override
    public Result<List<Integer>> getCoachListByVenueId(Integer venueId) {
        List<Integer> ids = cocahSigningVenueService.list(new QueryWrapper<CocahSigningVenue>().eq("venue_id", venueId).eq("state", 0)).stream().map(mi -> mi.getCocahId()).collect(Collectors.toList());
        if (ids == null || ids.size() <= 0) {
            return Result.getInstanceList(Integer.class).setData(ids);
        }
        return Result.getInstanceList(Integer.class).setData(ids).setCode(200);
    }

    @Override
    public Result<Integer> getVenueIdToCoachId(Integer cocahId) {
        CocahSigningVenue cocahSigningVenueDB = cocahSigningVenueService.getOne(new QueryWrapper<CocahSigningVenue>().eq("cocah_id", cocahId));

        if (cocahSigningVenueDB == null) {
            return Result.getInstance(Integer.class).setCode(500).setMsg("该教练没有场馆签约").setData(null);
        }

        return Result.getInstance(Integer.class).setCode(200).setMsg("根据教练id查询场馆id成功").setData(cocahSigningVenueDB.getVenueId());

    }

    private void makeSureURL(String source) {
        try {
            URL url = new URL(source);
            URLConnection uc = url.openConnection();
            InputStream in = uc.getInputStream();
            if (source.equalsIgnoreCase(uc.getURL().toString()))
                in.close();
        } catch (Exception e) {
            throw new SigningException(SigningResultCode.URI_NOTEXIST.getCode(), SigningResultCode.URI_NOTEXIST.getMessage());
        }
    }

    public Long stringToLong(String time) {
        Date date = new Date();
        try {
            date = new SimpleDateFormat("yyyy-MM-dd").parse(time);
        } catch (Exception e) {
            //LOGGER.error("时间转换错误, string = {}", s, e);
        }
        return date.getTime();
    }


}

